<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws.
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.).
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations).
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Account/classes/PhpFox_ServiceFriends.class.php, $Author:  $ */



/** Service for working with friends
 *
 * @package module.account
 * @version $Id: PhpFox_ServiceFriends.class.php 416 2008-03-28 07:20:51Z phpfoxsv $
 *
 */
class PhpFox_Mod_Account_ServiceFriends extends BaseService
{
    /** Get friends count for selected account
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return int number of friends
     */
	function getFriendsCount(&$oAcc)
	{
	    return $oAcc->oDb->getField('SELECT COUNT(*) FROM '.App::getT('friends').
                                    '  WHERE user = "'.$oAcc->aData['user'].'"');
	}

	/** Return friends list (NOT USED ANYMORE)
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return array friends info
	 */
	function getFriendsList(&$oAcc, $iPage=0, $iPageSize=0, $sSort='', $bIsTop = false)
	{
        $iCnt = $this->getFriendsCount($oAcc);

		$aRows = array();

		if ( $iCnt )
		{
			$iOffset = DbItem::_getOffset($iPage, $iPageSize, $iCnt);

			$sExtra = ($iPageSize) ?  "DESC LIMIT ".$iOffset.",".$iPageSize."" : "";

			$aRows = $this->oDatabase->getRows("SELECT friend,top FROM ". App::getT('friends') ." ".
				" WHERE user = '". $oAcc->aData['user'] ."' ".
				// " AND top = '0' ".
				" ORDER BY time ".
				" ".$sExtra ."");

			foreach($aRows as $k=>$v)
			{
				$aRows[$k]['user'] = $v['friend'];

				if ( $bIsTop )
				{
					if ( $v['top'] )
					{
                		$aRows[$k]['is_top_friend'] = true;
                	}
				}
			}
		}
        return array($aRows, $iCnt);
	}

	/** Return friends list
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return array friends info
	 */
	function getFriendList(&$oAcc, $iPage=0, $iPageSize=0, $sSort='', $bIsTop = false)
	{
		$aRows = array();
		
		$oReq =& App::getRequest();
		$sUserName = $oReq->get('username');

    	$iCnt = ($sUserName ? $this->oDatabase->getField("SELECT COUNT(*) FROM " . App::getT('friends') . " WHERE user = '" . $oAcc->aData['user'] . "' AND friend LIKE '%" . $this->oDatabase->escape($sUserName) . "%'")  : $oAcc->aData['c_friends']);

    	if ( $iCnt )
		{
			$iOffset = DbItem::_getOffset($iPage, $iPageSize, $iCnt);

			$aRows = $this->oDatabase->getRows("SELECT u.user, f.top FROM ". App::getT('friends') ." AS f ".
				" LEFT JOIN " . App::getT('user') . " AS u ON f.friend = u.user " .
				" WHERE f.user = '". $oAcc->aData['user'] ."' ".
				($sUserName ? " AND f.friend LIKE '%" . $this->oDatabase->escape($sUserName) . "%' " : '') .
				" ORDER BY f.time ".
				" DESC LIMIT ".$iOffset.",".$iPageSize." ");

			foreach($aRows as $k=>$v)
			{
				if ( $bIsTop )
				{
					if ( $v['top'] )
					{
                		$aRows[$k]['is_top_friend'] = true;
                	}
				}
			}
		}
        return array($aRows, $iCnt);
	}

	/** Return friends list
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return array friends info
	 */
	function getFriendListTop(&$oAcc)
	{
		$aRows = array();

		$aRows = $this->oDatabase->getRows("SELECT u.user AS friend FROM ". App::getT('friends') ." AS f".
			" LEFT JOIN " . App::getT('user') . " AS u ON f.friend = u.user " .
			" WHERE f.user = '". $oAcc->aData['user'] ."' ".
			" AND f.top = '1' ".
			" ORDER BY f.top_order ASC".
			" LIMIT 0,". ($oAcc->aData['total_friends'] ? $oAcc->aData['total_friends'] : App::getParam('public.top.friends')) ." ");

        return $aRows;
	}

	/** Return friends list
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return array friends info
	 */
	function getTopFriendsList($sUser, $iTotal = 0)
	{
		$aRows = array();

		$aRows = $this->oDatabase->getRows("SELECT u.user AS friend FROM ". App::getT('friends') ." AS f ".
			" LEFT JOIN " . App::getT('user') . " AS u ON f.friend = u.user " .
			" WHERE f.user = '". $sUser ."' ".
			" AND f.top = '1' ".
			" ORDER BY f.top_order ASC ".
			" LIMIT 0,". ($iTotal ? $iTotal : App::getParam('public.top.friends')) ." ");

        return $aRows;
	}

	/** Return friends list
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return array friends info
	 */
	function getTopFriendList(&$oAcc, $iPage=0, $iPageSize=0, $sSort='', $bIsTop = false)
	{
		$aRows = array();
		$aRows1 = array();
		$aRows2 = array();

		$iCnt = $oAcc->aData['c_friends'];

		if ( $iCnt )
		{
			$aRowsTop = $this->oDatabase->getRows("SELECT friend FROM ". App::getT('friends') ." ".
				" WHERE user = '". $oAcc->aData['user'] ."' AND top = '1' ".
				" LIMIT 0,". App::getParam('public.top.friends') ." ");

			$aRowsUser = $this->oDatabase->getRows("SELECT friend FROM ". App::getT('friends') ." ".
				" WHERE user = '". $oAcc->aData['user'] ."' AND top = '0' ".
				" ORDER BY time ".
				" DESC LIMIT 0,". ($iPageSize - count($aRowsTop)) ." ");

			foreach($aRowsUser as $k=>$v)
			{
				$aRows1[$k]['user'] = $v['friend'];
			}

			foreach($aRowsTop as $k=>$v)
			{
				$aRows2[$k]['user'] = $v['friend'];
			}

			if ( count($aRows2) > 0 )
			{
				$aRows = array_merge($aRows2, $aRows1);
			}
			else
			{
				$aRows = $aRows1;
			}
		}

        return array($aRows, $iCnt);
	}

	/** Returns list of friends requests ('request to me')
	 * @var PhpFox_Mod_Account_ItemAcc $oAcc user account
	 * @return array list of friend requests
	 */
	function getRequestsList(&$oAcc, $iPage=0, $iPageSize=0, $sSort='')
	{
        $iCnt = $oAcc->oDb->getField('
        	SELECT COUNT(*) 
        	FROM '.App::getT('buddy_add').' AS b 
        		JOIN ' . App::getT('user') . ' AS u 
        			ON b.user = u.user
        	WHERE b.friend = "'.$oAcc->aData['user'].'"
        ');
        
        $aRows = array();
        if ($iCnt)
        {
            $iOffset = DbItem::_getOffset($iPage, $iPageSize, $iCnt);
    	    $sSql = 'SELECT ba.id AS req_id, u.* FROM '.App::getT('buddy_add').' AS ba '.
    	            '  INNER JOIN '.$oAcc->sTable.' u ON ba.user = u.user '.
    	            '  WHERE ba.friend = "'.$oAcc->aData['user'].'"'.
                    ($sSort?(' ORDER BY '.$sSort):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');
    	    $aRows = $oAcc->oDb->getRows($sSql);
        }
        return array($aRows, $iCnt);
	}

	function updateCount($sUser)
	{
		$iCnt = $this->oDatabase->getRow("SELECT COUNT(*) AS count FROM ". App::getT('friends') ." WHERE user = '". $sUser ."'");

		$this->oDatabase->query("UPDATE ". App::getT('user') ." SET c_friends = '". $iCnt['count'] ."' WHERE user = '". $sUser ."'");

		return true;
	}

	/** Checks that (current) user added to friends list of target user
	 * @param PhpFox_Mod_Account_ItemAccount $oUserName   target user
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @return boolean
	 */
	function isFriend(&$oUser, &$oCurrUser)
	{
	    if (!$oUser)
	    {
	        return false;
	    }
	    if ($oUser->aData['user'] == $oCurrUser->aData['user'])
	    {
	        return true;
	    }
	    if (!$oUser && !$oCurrUser)
	    {
	        return false;
	    }
	    if (!$oCurrUser)
	    {
	        $oSrvSec = &$this->_oModule->getService('Security');
	        /* @var $oSrvSec PhpFox_Mod_Account_ServiceSecurity */
	        $oCurrUser = $oSrvSec->getCurrentUser();
	    }
	    $iCnt = 0;
	    if (isset($oCurrUser->aData) and isset($oUser->aData))
	    {
			$iGetCount = $this->checkIsFriend($oUser->aData['user'], $oCurrUser->aData['user']);
			return (($iGetCount) > 0);
	    }
	    if ( isset($iCnt) && isset($iCntR) )
	    {
        	return (($iCnt+$iCntR) > 0);
		}
	}

	function checkIsFriend($sUser, $sFriend)
	{
		static $aCnt = array();
		
		if (!isset($aCnt[$sUser][$sFriend]['count1']) && !isset($aCnt[$sUser][$sFriend]['count2']))
		{
			$aCnt[$sUser][$sFriend]['count1'] = $this->oDatabase->getField('SELECT COUNT(*) '.
	        	' FROM '.App::getT('friends').' '.
	            ' WHERE user = "'.$sUser.'" '.
	            ' AND friend = "'.$sFriend.'"');
	
			$aCnt[$sUser][$sFriend]['count2'] = $this->oDatabase->getField('SELECT COUNT(*) '.
	        	' FROM '.App::getT('friends').' '.
	            ' WHERE friend = "'.$sUser.'" '.
	            '   AND user = "'.$sFriend.'"');
		}            

		return ($aCnt[$sUser][$sFriend]['count1']+$aCnt[$sUser][$sFriend]['count2']);
	}

	/** Is (current) user already sent friend request (pending) to target user
	 * @param PhpFox_Mod_Account_ItemAccount $oUserName   target user
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @return boolean true - has friends request, false - no friend request
	 */
	function isFriendReqest(&$oUser, &$oCurrUser)
	{
	    if (!$oCurrUser)
	    {
	        $oSrvSec = &$this->_oModule->getService('Security');
	        /* @var $oSrvSec PhpFox_Mod_Account_ServiceSecurity */
	        $oCurrUser = $oSrvSec->getCurrentUser();
	    }
	    if (!$oCurrUser)
	    	return false;


	   	$iCnt = $oUser->oDb->getField('SELECT COUNT(*) '.
                                      ' FROM '.App::getT('buddy_add').' '.
                                      ' WHERE friend = "'.$oUser->aData['user'].'" '.
                                      '   AND user = "'.$oCurrUser->aData['user'].'"');

	   	$iCntR = $oUser->oDb->getField('SELECT COUNT(*) '.
                                      ' FROM '.App::getT('buddy_add').' '.
                                      ' WHERE user = "'.$oUser->aData['user'].'" '.
                                      '   AND friend = "'.$oCurrUser->aData['user'].'"');

	   	return (($iCnt+$iCntR) > 0);
	}

	/** Add friend request
	 * @param PhpFox_Mod_Account_ItemAccount $oAddUser    target user
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @return int request ID or false if error occured
	 */
	function addFriendRequest($oAddUser, $oCurrUser)
	{
	    $oTpl = &App::getTemplate();
	    $aVals = array(
	        'user'   => $oCurrUser->aData['user'],
	        'friend' => $oAddUser->aData['user'],
	        'time'   => time(),
	    );

	    $iId = $oAddUser->oDb->insert(App::getT('buddy_add'), $aVals);
	    if ($iId && $oAddUser->aData['not_5'])  //not_5 -- notify friend reqest by mail
	    {
			$oMailer = App::newObject('mail_Mailer');
			/* @var oMailer mail_Mailer */

			$aVars = array(
				'SITENAME' => App::getSetting('site_name'),
				'TO'       => $oAddUser->aData['user'],
			    'FROM'     => $oCurrUser->aData['user'],
			    'URL'      => App::makeUrl('public.account.friends', array('sect' => 'request')),
			);

			$oMailer->send('email_newbuddy', $oAddUser->aData['email'], App::format('core.email.newbuddy'), $aVars);
        }
        return $iId;
	}

	/** Add friend instantly
	 * @param PhpFox_Mod_Account_ItemAccount $oAddUser  target user (friend to add)
	 * @param PhpFox_Mod_Account_ItemAccount $oUser     current user (to whom friend will be added)
	 * @return int request ID or false if error occured
	 */
	function addFriend(&$oAddUser, &$oUser)
	{
	    $iId = $this->oDatabase->getField('SELECT id FROM '.App::getT('friends').
	                           ' WHERE user = "'.$oUser->aData['user'].'"'.
	                           ' AND friend = "'.$oAddUser->aData['user'].'"');
	    if (!$iId)
	    {
    	    $aVals = array(
    	        'user'   => $oUser->aData['user'],
    	        'friend'  => $oAddUser->aData['user'],
    	        'time'   => time(),
    	    );
    	    $iId = $this->oDatabase->insert(App::getT('friends'), $aVals);
    	    $this->updateCount($oUser->aData['user']);

    	    $aVals = array(
    	        'user'   => $oAddUser->aData['user'],
    	        'friend'  => $oUser->aData['user'],
    	        'time'   => time(),
    	    );
    	    $iId = $this->oDatabase->insert(App::getT('friends'), $aVals);
    	    $this->updateCount($oAddUser->aData['user']);
	    }
	    return $iId;
	}

	function UserAddBuddy($sUser, $sFriend)
	{
	    $iId = $this->oDatabase->getField('SELECT COUNT(*) FROM '.App::getT('friends').
	                           ' WHERE user = "'. $sUser .'"'.
	                           ' AND friend = "'. $sFriend .'"');
	    if ($iId == 0)
	    {
    	    $aVals = array(
    	        'user'   => $sUser,
    	        'friend'  => $sFriend,
    	        'time'   => time(),
    	    );
    	    $iId = $this->oDatabase->insert(App::getT('friends'), $aVals);
    	    $this->updateCount($sUser);

    	    $aVals = array(
    	        'user'   => $sFriend,
    	        'friend'  => $sUser,
    	        'time'   => time(),
    	    );
    	    $iId = $this->oDatabase->insert(App::getT('friends'), $aVals);
    	    $this->updateCount($sFriend);

    	    return true;
	    }

	    return false;
	}

	/** Approve selected friend request
	 * @var mixed $iReqId request Id(s)
	 */
	function approveRequest($mReqId, $oAcc)
	{
	    if (!is_array($mReqId))
	    {
	        $mReqId = array($mReqId);
	    }

        $oDb = &Database::get();
        /* @var $oDb Database */

	    //get info
        $aRes = array();
        foreach($mReqId as $iReqId)
        {
		    $iReqId = intval($iReqId);
            $sSql = 'SELECT user, friend FROM '.App::getT('buddy_add').
                    '  WHERE id = '.$iReqId;
            $aReq = $oDb->getRow($sSql);

            if ( !isset($aReq['friend']) )
            {
            	return false;
            }

            //check request reciever = current user
            if ($aReq['friend'] == $oAcc->aData['user'])
            {
                //add to friends
                $aVals = array(
                	'user'   => $aReq['friend'],
                    'friend'  => $aReq['user'],
                    'time'   => time(),
                );
                $oDb->insert(App::getT('friends'), $aVals);
                $this->updateCount($aReq['friend']);

                $aVals = array(
                    'user'   => $aReq['user'],
                    'friend'  => $aReq['friend'],
                    'time'   => time(),
                );
                $oDb->insert(App::getT('friends'), $aVals);
                $this->updateCount($aReq['user']);

               	//delete requests
               	$oDb->query('DELETE FROM '.App::getT('buddy_add').
					' WHERE id='.$iReqId);

                if ($aReq['user'])
                {
                    $aRes[] = array('id' => $iReqId, 'user'=>$aReq['user']);
                }
             }
        }
        return $aRes;
	}

	/** Deny selected friend request
	 * @var int $iReqId request Id
	 */
	function denyRequest($mReqId, $oAcc)
	{
        $oDb = &Database::get();
	    if (!is_array($mReqId))
	    {
	        $mReqId = array($mReqId);
	    }
	    $aRes = array();
	    foreach($mReqId as $iReqId)
        {
    	    $iReqId = intval($iReqId);
            //get info
            $sSql = 'SELECT user, friend FROM '.App::getT('buddy_add').
                    '  WHERE id = '.$iReqId;
            $aReq = $oDb->getRow($sSql);
            /* @var $oDb Database */

            //delete requests
            //check request reciever = current user
            if ($aReq['friend'] == $oAcc->aData['user'])
            {
                //delete requests
                $oDb->query('DELETE FROM '.App::getT('buddy_add').
                            ' WHERE id='.$iReqId);
                if ($aReq['user'])
                {
                    $aRes[] = array('id' => $iReqId, 'user'=>$aReq['user']);
                }
             }
        }
        return $aRes;
	}

	/** Returns list of pending friend requests ('my request').
	 * @var PhpFox_Mod_Account_ItemAcc $oAcc user account
	 * @return array list of pending requests
	 */
	function getPendingList($oAcc, $iPage=0, $iPageSize=0, $sSort='')
	{
	    $iCnt = $oAcc->oDb->getField('SELECT COUNT(*) FROM '.App::getT('buddy_add').
                                     '  WHERE user = "'.$oAcc->aData['user'].'"');
        $aRows = array();
        if ($iCnt)
        {
            $iOffset = DbItem::_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT ba.id AS buddy_add_id, u.user FROM '.App::getT('buddy_add').' AS ba '.
    	            '  INNER JOIN '.$oAcc->sTable.' u ON ba.friend = u.user '.
    	            '  WHERE ba.user = "'.$oAcc->aData['user'].'"'.
                    ($sSort?(' ORDER BY '.$sSort):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');
            $aRows = $oAcc->oDb->getRows($sSql);
        }
	    return array($aRows, $iCnt);
	}

	/** Remove user from friends
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @param string                         $sFriendUser name of user to delete from friends
	 */
	function deleteFriend($oCurrUser, $sFriendUser)
	{
		$this->oDatabase->query("DELETE FROM ". App::getT('friends') ." WHERE user = '". $oCurrUser->aData['user'] ."' AND friend = '". $sFriendUser ."' LIMIT 1");
		$this->oDatabase->query("DELETE FROM ". App::getT('friends') ." WHERE friend = '". $oCurrUser->aData['user'] ."' AND user = '". $sFriendUser ."' LIMIT 1");
		$this->updateCount($oCurrUser->aData['user']);
		$this->updateCount($sFriendUser);
	}

	/** Make/unmake top friends
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @param string                         $sFriendUser name of user to delete from friends
	 * @param bool                           $bIsTop       true - make top, false - unmake top
	 */
	function setTopFriend($oCurrUser, $sFriendUser, $bIsTop = true)
	{
	    $oDb = &Database::get();
	    /* @var $oDb Database */

	    //try to find user2buddy top friendship
	    $aVals = array(
    	    'top' => ($bIsTop ? '1' : '0'),
	    );
	    $oDb->update(App::getT('friends'), $aVals,
                     ' (user = "'.$oDb->escape($oCurrUser->aData['user']).'"  AND '.
	                 '  friend = "'.$oDb->escape($sFriendUser).'")');

	}

	function reachedTopLimit(&$oAcc)
	{
		$aCheck = $this->oDatabase->getRow("SELECT COUNT(*) AS count FROM ". App::getT('friends') ." WHERE user = '". $oAcc->aData['user'] ."' ".
			" AND top = '1' ");
		return $aCheck['count'];
	}

	function reachedTopLimitFriend($sUser)
	{
		$aCheck = $this->oDatabase->getRow("SELECT COUNT(*) AS count FROM ". App::getT('friends') ." WHERE user = '". $sUser ."' ".
			" AND top = '1' ");
		return $aCheck['count'];
	}

	/** Is given friend "top" for current user
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @param string                         $sFriendUser name of user to delete from friends
	 * @return bool true - top friend, false - otherwise
	 */
	function userIsTopFriends($sCurrUser, $sFriendUser)
	{
		$sSql = "SELECT COUNT(*) FROM ". App::getT('friends') ."
			WHERE user = '". $sCurrUser ."' AND friend = '". $sFriendUser ."' AND top = '1'
		";
		return ($this->oDatabase->getField($sSql) > 0);
	}

	/** Is given friend "top" for current user
	 *
	 * @param PhpFox_Mod_Account_ItemAccount $oCurrUser   current user
	 * @param string                         $sFriendUser name of user to delete from friends
	 * @return bool true - top friend, false - otherwise
	 */
	function isTopFriends($oCurrUser, $sFriendUser)
	{
		return false;

	    $oDb = &Database::get();
	    /* @var $oDb Database */

	    $sSql = 'SELECT COUNT(*) FROM '.App::getT('friends').
                ' WHERE  (user = "'.$oDb->escape($oCurrUser->aData['user']).'"  AND '.
	            '         buddy = "'.$oDb->escape($sFriendUser).'" AND '.
                '         user2buddy = 1) '.
                '   OR '.
                '        (buddy = "'.$oDb->escape($oCurrUser->aData['user']).'"  AND '.
	            '         user = "'.$oDb->escape($sFriendUser).'" AND '.
                '         user2buddy = 1) ';
        return ($oDb->getField($sSql) > 0);

	}
	
	function getIds($sUser)
	{
		$oDb = Database::get();
		$aRows = $oDb->getRows('
			SELECT u.id
			FROM ' . App::getT('friends') . ' AS f
				JOIN ' . App::getT('user') . ' AS u
					ON f.friend = u.user
			WHERE f.user = "' . $sUser . '"
		');
		$aFriends = array();
		foreach($aRows as $aRow)
		{
			$aFriends[] = $aRow['id'];
		}
		return $aFriends;
	}	
	
	/** Return friends String separated with comma
     * @param PhpFox_Mod_Account_ItemAccount $oAcc user object
     * @return string FriendsList
	 */
	function getFriendsString(&$oAcc, $sQuote='"')
	{
        $sResult = '';
        if ($iCnt = $this->getFriendsCount($oAcc))
        {
        	$iPage = 1;
	        $iPageSize = 200;
	        $iOffset = 0;
	        while ($iOffset<$iCnt)
            {
	            $sSql = ' SELECT friend '.
	                    ' FROM `'.App::getT('friends').'` AS f '.
	            		' WHERE (f.user = "'.$oAcc->aData['user'].'") '.
	                    ($iPageSize? (' LIMIT '.$iOffset.','.$iPageSize) : '' );
	            $aRows = $oAcc->oDb->getRows($sSql);
	            foreach($aRows as $aItem)
            		$sResult .= $sQuote . $aItem['friend'] . $sQuote . ',';
            	unset($aRows);
	            ++$iPage;
                $iOffset =  $iPageSize*($iPage-1);
		    }
		}
		if(''!=$sResult)
		{
			$sResult = substr($sResult,0,-1);
		}
        return $sResult;	    
	}
}
?>